package com.lft.examsys.controller;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.lft.examsys.entity.Permission;
import com.lft.examsys.model.IModel;
import com.lft.examsys.model.ValidationModelAndView;
import com.lft.examsys.service.PermissionService;
import com.lft.examsys.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/role")
public class RoleController {
    @Autowired
    private RoleService roleService;

    @Autowired
    private PermissionService permissionService;


    @GetMapping("/manage")
    @PreAuthorize("hasAnyAuthority('role.manage')")
    public ValidationModelAndView roleManagePage(IModel model, Integer page, Integer size) {
        return model.validation("/admin/RoleManage", () -> {
            roleService.getRoleByPage(model, page, size, "roles");
        }, model::err);
    }

    @PostMapping("/delete/{id}")
    @PreAuthorize("hasAnyAuthority('role.delete')")
    public ValidationModelAndView delete(IModel model, @PathVariable String id, Integer page, Integer size) {
        return model.validation("/admin/RoleManage", () -> {
            roleService.getRoleByPage(model, page, size, "roles");
            if (id.equalsIgnoreCase("admin") || id.equalsIgnoreCase("default") || !roleService.delete(id))
                model.failure("删除失败");
            roleService.delete(id);
        }, model::err);
    }

    @GetMapping("/edit/{id}")
    @PreAuthorize("hasAnyAuthority('role.edit')")
    public ValidationModelAndView edit(IModel model, @PathVariable String id) {
        return model.validation("/admin/RoleEdit", () -> {
            List<Permission> permissions = permissionService.getAllPermission();
            List<String> activePermissions = permissionService.getActivePermissionIdByRoleId(id);
            model.add("permissions", permissions);
            model.add("activePermissions", activePermissions);
        }, model::err);
    }

    @GetMapping("/add")
    @PreAuthorize("hasAnyAuthority('role.add')")
    public ValidationModelAndView addPage(IModel model) {
        return model.validation("/admin/RoleAdd", () -> {
            List<Permission> permissions = permissionService.getAllPermission();
            model.add("permissions", permissions);
        }, model::err);
    }

    @PostMapping("/add")
    @PreAuthorize("hasAnyAuthority('role.add')")
    public ValidationModelAndView add(IModel model, String id, String name, HttpServletRequest req) {
        return model.validation("redirect:/role/manage", () -> {
            List<String> allPermission = permissionService.getAllPermissionName();
            Map<String, String[]> selections = req.getParameterMap();
            roleService.add(id, name);
            for (String key : selections.keySet()) {
                if (StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(id) && selections.get(key)[0].equalsIgnoreCase("on") && allPermission.contains(key)) {
                    permissionService.AddPermission(id, key);
                }
            }
        }, model::err);
    }

    @PostMapping("/update/{id}")
    @PreAuthorize("hasAnyAuthority('role.edit')")
    public ValidationModelAndView update(IModel model, @PathVariable String id, HttpServletRequest req) {
        return model.validation("redirect:/role/manage", () -> {
            List<String> permissions = permissionService.getActivePermissionIdByRoleId(id);
            Map<String, String[]> selections = req.getParameterMap();
            for (String key : selections.keySet()) {
                if (StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(id) && selections.get(key)[0].equalsIgnoreCase("on") && !permissions.contains(key)) {
                    permissionService.AddPermission(id, key);
                }
                permissions.removeIf(x -> x.equalsIgnoreCase(key));
            }

            for (String permission : permissions) {
                permissionService.RemovePermission(id, permission);
            }
        }, model::err);
    }
}
